<template>
  <div class="app-container">
    <!--搜索表单-->
    <el-form :inline="true" :model="searchForm" class="demo-form-inline">
      <el-form-item label="用户名">
        <el-input
          v-model="searchForm.username"
          placeholder="请输入用户名"
        />
      </el-form-item>
      <el-form-item label="请求方法">
        <el-select v-model="searchForm.method" placeholder="请选择" clearable>
          <el-option label="GET" value="GET" />
          <el-option label="POST" value="POST" />
          <el-option label="PUT" value="PUT" />
          <el-option label="DELETE" value="DELETE" />
        </el-select>
      </el-form-item>
      <el-form-item label="请求URL">
        <el-input
          v-model="searchForm.url"
          placeholder="请输入URL"
        />
      </el-form-item>
      <el-form-item label="IP地址">
        <el-input
          v-model="searchForm.ip"
          placeholder="请输入IP地址"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="search">查询</el-button>
        <el-button type="info" @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 数据统计图表 -->
    <el-row :gutter="20" style="margin-bottom: 20px;">
      <el-col :span="24">
        <el-card shadow="hover">
          <div slot="header" class="clearfix">
            <span>系统日志统计</span>
            <!-- <el-radio-group v-model="chartType" size="mini" style="float: right;">
              <el-radio-button label="method">请求方法</el-radio-button>
              <el-radio-button label="status">请求状态</el-radio-button>
              <el-radio-button label="user">用户分布</el-radio-button>
            </el-radio-group> -->
          </div>
          <div style="display: flex; gap: 20px;">
            <!-- <div v-show="chartType === 'method'" id="logsMethodChart" style="flex: 1; height: 300px;" />
            <div v-show="chartType === 'status'" id="logsStatusChart" style="flex: 1; height: 300px;" />
            <div v-show="chartType === 'user'" id="logsUserChart" style="flex: 1; height: 300px;" /> -->

             <div id="logsMethodChart" style="flex: 1; height: 300px;" />
            <div id="logsStatusChart" style="flex: 1; height: 300px;" />
            <div id="logsUserChart" style="flex: 1; height: 300px;" />
          </div>
        </el-card>
      </el-col>
    </el-row>

    <!--表格-->
    <el-table
      :data="tableData"
      style="width: 100%"
      border
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column type="index" label="序号" width="60" align="center" />
      <el-table-column prop="username" label="用户名" align="center" />
      <el-table-column prop="operation" label="操作描述" align="center" />
      <el-table-column prop="method" label="请求方法" align="center">
        <template slot-scope="scope">
          <el-tag
            :type="getMethodType(scope.row.method)"
            effect="plain"
          >{{ scope.row.method }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="url" label="请求URL" align="center" />
      <el-table-column prop="ip" label="IP地址" align="center" />
      <el-table-column label="状态" align="center">
        <template slot-scope="scope">
          <el-tag
            :type="scope.row.status === 1 ? 'success' : 'danger'"
            effect="plain"
          >{{ scope.row.status === 1 ? '成功' : '失败' }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" label="创建时间" align="center">
        <template slot-scope="scope">
          {{ formatDateTime(scope.row.createTime) }}
        </template>
      </el-table-column>
    </el-table>

    <!--分页工具条-->
    <el-pagination
      :current-page="currentPage"
      :page-sizes="[5, 10, 20, 50]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      style="margin-top: 20px; text-align: right;"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<script>
import { getLogs } from '@/api/logs'
import * as echarts from 'echarts'

export default {
  name: 'Logs',
  data() {
    return {
      // 搜索表单
      searchForm: {
        username: '',
        method: '',
        url: '',
        ip: ''
      },
      // 表格数据
      tableData: [],
      // 分页参数
      currentPage: 1,
      pageSize: 10,
      total: 0,
      // 选中的行
      multipleSelection: [],
      // 被选中的id数组
      selectedIds: [],
      // 图表类型
      chartType: 'method',
      // 图表实例
      methodChart: null,
      statusChart: null,
      userChart: null
    }
  },
  watch: {
    tableData: {
      handler(newVal) {
        this.$nextTick(() => {
          this.updateCharts()
        })
      },
      deep: true
    }
  },
  created() {
    this.fetchData()
  },
  mounted() {
    this.$nextTick(() => {
      this.initCharts()

      // 监听窗口大小变化，重新调整图表大小
      window.addEventListener('resize', this.resizeCharts)
    })
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.resizeCharts)

    // 销毁图表实例
    if (this.methodChart) this.methodChart.dispose()
    if (this.statusChart) this.statusChart.dispose()
    if (this.userChart) this.userChart.dispose()
  },
  methods: {
    // 初始化图表
    initCharts() {
      this.methodChart = echarts.init(document.getElementById('logsMethodChart'))
      this.statusChart = echarts.init(document.getElementById('logsStatusChart'))
      this.userChart = echarts.init(document.getElementById('logsUserChart'))

      this.updateCharts()
    },

    // 更新图表数据
    updateCharts() {
      if (!this.tableData.length) return

      // 请求方法统计
      const methodStats = {}
      // 请求状态统计
      const statusStats = { '成功': 0, '失败': 0 }
      // 用户统计
      const userStats = {}

      this.tableData.forEach(log => {
        // 统计请求方法
        if (methodStats[log.method]) {
          methodStats[log.method]++
        } else {
          methodStats[log.method] = 1
        }

        // 统计请求状态
        if (log.status === 1) {
          statusStats['成功']++
        } else {
          statusStats['失败']++
        }

        // 统计用户
        if (userStats[log.username]) {
          userStats[log.username]++
        } else {
          userStats[log.username] = 1
        }
      })

      // 设置请求方法图表
      const methodData = Object.keys(methodStats).map(key => ({
        name: key,
        value: methodStats[key]
      }))

      this.methodChart.setOption({
        title: {
          text: '请求方法分布',
          left: 'center'
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          data: Object.keys(methodStats)
        },
        series: [
          {
            name: '请求方法',
            type: 'pie',
            radius: '50%',
            data: methodData,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      })

      // 设置请求状态图表
      const statusData = Object.keys(statusStats).map(key => ({
        name: key,
        value: statusStats[key]
      }))

      this.statusChart.setOption({
        title: {
          text: '请求状态分布',
          left: 'center'
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          data: Object.keys(statusStats)
        },
        series: [
          {
            name: '请求状态',
            type: 'pie',
            radius: '50%',
            data: statusData,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      })

      // 设置用户分布图表
      const userData = Object.keys(userStats).map(key => ({
        name: key,
        value: userStats[key]
      }))

      this.userChart.setOption({
        title: {
          text: '用户操作分布',
          left: 'center'
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b}: {c} ({d}%)'
        },
        legend: {
          orient: 'vertical',
          left: 'left',
          data: Object.keys(userStats)
        },
        series: [
          {
            name: '用户操作',
            type: 'pie',
            radius: '50%',
            data: userData,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      })
    },

    // 调整图表大小
    resizeCharts() {
      if (this.methodChart) this.methodChart.resize()
      if (this.statusChart) this.statusChart.resize()
      if (this.userChart) this.userChart.resize()
    },

    // 获取日志数据
    fetchData() {
      const params = {
        ...this.searchForm,
        page: this.currentPage,
        pageSize: this.pageSize
      }

      getLogs(params).then(response => {
        const { data } = response.data
        this.tableData = data.records
        this.total = data.total
        this.currentPage = data.current
        this.pageSize = data.size
      }).catch(error => {
        console.error('获取日志数据失败', error)
        this.$message.error('获取日志数据失败')
      })
    },

    // 搜索
    search() {
      this.currentPage = 1
      this.fetchData()
    },

    // 重置表单
    resetForm() {
      this.searchForm = {
        username: '',
        method: '',
        url: '',
        ip: ''
      }
      this.currentPage = 1
      this.fetchData()
    },

    // 处理页码变化
    handleCurrentChange(val) {
      this.currentPage = val
      this.fetchData()
    },

    // 处理每页条数变化
    handleSizeChange(val) {
      this.pageSize = val
      this.currentPage = 1
      this.fetchData()
    },

    // 处理选择变化
    handleSelectionChange(val) {
      this.multipleSelection = val
      this.selectedIds = val.map(item => item.id)
    },

    // 格式化日期时间
    formatDateTime(dateTime) {
      if (!dateTime) return ''
      return dateTime.replace('T', ' ')
    },

    // 获取请求方法对应的标签类型
    getMethodType(method) {
      const methodMap = {
        'GET': 'success',
        'POST': 'primary',
        'PUT': 'warning',
        'DELETE': 'danger'
      }
      return methodMap[method] || 'info'
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.el-card {
  margin-bottom: 20px;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}
.clearfix:after {
  clear: both;
}
</style>
